package com.itheima.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.reggie.common.R;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.service.CategoryService;
import com.itheima.reggie.service.DishService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/dish")
public class DishController {

    @Autowired
    private DishService dishService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 新增菜品
     * @author Mosetian
     * @date 2022-9-12 0:53
     * @param	dishDto
     * @return R<String>
     */
    @PostMapping
    public R save(@RequestBody DishDto dishDto) {
        dishService.saveDishWithFlavors(dishDto);

        String key = "dish_" + dishDto.getCategoryId() + "_1";
        redisTemplate.delete(key);

        return R.success("添加成功");
    }

    /**
     * 菜品信息分页查询
     * @author Mosetian
     * @date 2022-9-12 21:42
     * @param	page
     * @param	pageSize
     * @param	name
     * @return R<Page>
     */
    @GetMapping("/page")
    public R pageQuery(int page, int pageSize, String name){
        //构造分页构造器对象
        Page<Dish> pageInfo = new Page<>(page, pageSize);

        //条件构造器
        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
        //添加过滤条件(也许为空)
        queryWrapper.like(name != null, Dish::getName, name);
        //添加排序条件
        queryWrapper.orderByDesc(Dish::getUpdateTime);

        //执行分页查询
        dishService.page(pageInfo, queryWrapper);

        List<Dish> records = pageInfo.getRecords();
        long total = pageInfo.getTotal();
        List<DishDto> dishDtos = new ArrayList<>();

        for (Dish dish : records) {
            Long categoryId = dish.getCategoryId();

            DishDto dishDto = new DishDto();
            if (categoryService.getById(categoryId) != null){

                String categoryName = categoryService.getById(categoryId).getName();

                // 新建一个DishDto 将分类名称set进入

                dishDto.setCategoryName(categoryName);
            }



            //先将查询到的dish对象里的属性值拷贝到dishDto对象中
            BeanUtils.copyProperties(dish, dishDto);
            // 还需要将Dish dish 数据放入到 DishDto dishDto 里面
            dishDtos.add(dishDto);
        }

        Map map = new HashMap();
        map.put("records", dishDtos);
        map.put("total", total);

        return R.success(map);
    }

    /**
     * 根据id查询菜品数据，用于回显
     * @author Mosetian
     * @date 2022-9-13 15:53
     * @param	id
     * @return R
     */
    @GetMapping("/{id}")
    public R getDishForUpdate(@PathVariable Long id){
        DishDto dishDto = dishService.getByIdWithFlavor(id);
        return R.success(dishDto);
    }

    /**
     * 修改菜品
     * @author Mosetian
     * @date 2022-9-13 12:28
     * @param	dishDto
     * @return R
     */
    @PutMapping
    public R updateDish(@RequestBody DishDto dishDto){
        dishService.updateDishWithFlavor(dishDto);

        //清理某个分类下面的菜品缓存数据
        String key = "dish_" + dishDto.getCategoryId() + "_1";
        redisTemplate.delete(key);

        return R.success("修改菜品成功");
    }

    /**
     * 删除菜品,删除单个和批量删除共用一个接口
     * @author Mosetian
     * @date 2022-9-13 14:59
     * @param	ids
     * @return R
     */
    @DeleteMapping
    public R deleteDish(@RequestParam List<Long> ids){

        dishService.removeByIds(ids);

        return R.success("删除成功");
    }

    /**
     * 起售/停售 批量起售/批量停售
     * @author Mosetian
     * @date 2022-9-13 15:00
     * @param	ids
     */
    @PostMapping("/status/{status}")
    public R updateStatusById(@PathVariable Integer status,@RequestParam List<Long> ids){
        LambdaUpdateWrapper<Dish> qw = new LambdaUpdateWrapper<>();
        qw.set(Dish::getStatus,status);// set status = ?
        qw.in(Dish::getId,ids);//  where id in (1,2,3)
        dishService.update(qw);
        // update dish set status = ? where id = ?
        for (Long id : ids) {
            Dish dish = new Dish();
            dish.setId(id);
            dish.setStatus(status);
            dishService.updateById(dish);
        }
        return R.success("操作成功");
    }
    /*@PostMapping("/status/{status}")
    public R<String> updateStatusById(@PathVariable Integer status, Long[] ids) {
        // 增加日志验证是否接收到前端参数。
        // 通过id查询数据库。修改id为ids数组中的数据的菜品状态status为前端页面提交的status。
        for (int i = 0; i < ids.length; i++) {
            Long id=ids[i];
            //根据id得到每个dish菜品。
            Dish dish = dishService.getById(id);
            dish.setStatus(status);
            dishService.updateById(dish);
        }
        return R.success("修改菜品状态成功");
    }*/

    /**
     * 根据条件查询对应的分类菜品下菜品集合
     * @author Mosetian
     * @date 2022-9-15 9:29
     * @param	dish
     * @return R<List<Dish>>
     */
    @GetMapping("/list")
    public R<List<DishDto>> getDishesByCategoryId( Dish dish){
        /*LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(dish.getCategoryId() != null, Dish::getCategoryId, dish.getCategoryId());
        //添加条件，查询状态为1（起售状态）的菜品
        queryWrapper.eq(Dish::getStatus,1);
        //添加排序条件
        queryWrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);
        List<Dish> dishes = dishService.list(queryWrapper);*/

        //在list方法中,查询数据库之前,先查询缓存, 缓存中有数据, 直接返回
        List<DishDto> dishDtoList = null;
//动态构造key
        String key = "dish_" + dish.getCategoryId() + "_" + dish.getStatus();//dish_1397844391040167938_1
//先从redis中获取缓存数据
        dishDtoList = (List<DishDto>) redisTemplate.opsForValue().get(key);
        if(dishDtoList != null){
            //如果存在，直接返回，无需查询数据库
            return R.success(dishDtoList);
        }


        dishDtoList = dishService.listWithFlavor(dish);

        //如果不存在，需要查询数据库，将查询到的菜品数据缓存到Redis
        redisTemplate.opsForValue().set(key,dishDtoList,60, TimeUnit.MINUTES);

        return R.success(dishDtoList);
    }
}
